package ssd8.socket.http;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

/**
 * Class <em>Client</em> is a class representing a simple HTTP client.
 *
 * @author wben
 */

public class Client {

	/**
	 * default HTTP port is port 80
	 * 默认HTTP端口，设置为 80
	 */
	private static int port = 80;

	/**
	 * Allow a maximum buffer size of 8192 bytes
	 * 允许的最大缓冲区大小，设置为 8192字节
	 */
	private static int buffer_size = 8192;

	/**
	 * The end of line character sequence.
	 * 代表回车和换行的字符序列，设置为 "\r\n"
	 */
	private static String CRLF = "\r\n";

	/**
	 * Input is taken from the keyboard
	 * 从键盘读取输入的 BufferedReader对象
	 */
	static BufferedReader keyboard = new BufferedReader(new InputStreamReader(
			System.in));

	/**
	 * Output is written to the screen (standard out)
	 * 向屏幕（标准输出）写入输出的 PrintWriter对象
	 */
	static PrintWriter screen = new PrintWriter(System.out, true);

	public static void main(String[] args) {

		// args 赋值---类中赋值的硬编码形式
		// args = new String[] {"www.nwpu.edu.cn"};
		// args = new String[] {"www.baidu.com"};
		//args = new String[] {"www.5imx.com"};
		//args = new String[] {"127.0.0.1"};

		try {
			/**
			 * Create a new HttpClient object.
			 * 用于执行 HTTP请求
			 */
			HttpClient myClient = new HttpClient();

			/**
			 * Parse the input arguments.
			 * 解析命令行参数：程序期望接收一个参数，即要连接的服务器的主机名或 IP地址
			 * 如果没有成功获取，则提示并退出程序
			 */
			if (args.length != 1) {
				System.err.println("Usage: Client <server>");
				System.exit(0);
			}

			/**
			 * Connect to the input server
			 * 建立与服务器的连接
			 */
			myClient.connect(args[0]);

			/**
			 * Read the get request from the terminal.
			 * 从终端获取用户键盘输入的 HTTP请求
			 */
			screen.println(args[0] + " is listening to your request:");
			String request = keyboard.readLine();

			if (request.startsWith("GET")) {
				/**
				 * Ask the client to process the GET request.
				 * 处理 GET请求
				 */
				// 由于现在大部分网站协议都是1.1，请求头需要使用Connection: close 和Host 属性才可正常访问
				myClient.processGetRequest(request + CRLF + "Connection: close" + CRLF + "Host: " + args[0]);
			} else if (request.startsWith("PUT")) {
				/**
				 * Ask the client to process the PUT request.
				 * 处理 PUT请求
				 */
				myClient.processPutRequest(request);
			} else {
				/**
				 * Do not process other request.
				 * 对于其他请求，显示 "Bad request!"，然后关闭客户端连接
				 */
				screen.println("Bad request! \n");
				myClient.close();
				return;
			}

			/**
			 * Get the headers and display them.
			 * 获取 HTTP响应头，并将其显示在屏幕上
			 */
			screen.println("Header: \n");
			screen.print(myClient.getHeader() + "\n");
			screen.flush();

			if (request.startsWith("GET")) {
				/**
				 * Ask the user to input a name to save the GET resultant web page.
				 * 如果是 GET请求，要求用户输入保存响应数据的文件名，并将响应数据保存到该文件中
				 */
				screen.println();
				screen.print("Enter the name of the file to save: ");
				screen.flush();
				String filename = keyboard.readLine();
				// 设置默认保存在项目的clientDir文件中
				FileOutputStream outfile = new FileOutputStream(System.getProperty("user.dir") +
						"/clientDir/" + filename);

				/**
				 * Save the response to the specified file.
				 * 保存响应获取的文件
				 */
				String response = myClient.getResponse();
				outfile.write(response.getBytes("iso-8859-1"));
				outfile.flush();
				outfile.close();
			}

			/**
			 * Close the connection client.
			 * 关闭连接
			 */
			myClient.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
